#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <assert.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>

#define FRAME_FORMAT V4L2_PIX_FMT_NV12

#define FRAME_WIDTH  	560
#define FRAME_HEIGHT 	320
#define FPS				30

int main(int argc, char *argv[])
{
	struct v4l2_capability vid_caps;
	struct v4l2_format vid_format;
	FILE* in_fp;

	int framesize =  FRAME_WIDTH * FRAME_HEIGHT* 15 / 10;

	char *buffer;

  	const char *video_device;
	const char *infile;
	int fdwr = 0;
	int ret_code = 0;

	int i;

	if(argc != 3) {
		printf("examples:\n");
		printf("\ttest_yuv /dev/video0 output.nv12\n");
		return -1;
	}

	video_device = argv[1];
	infile = argv[2];
	printf("video_device = %s\n", video_device);
	printf("infile = %s\n", infile);
	fdwr = open(video_device, O_RDWR);
	assert(fdwr >= 0);
	in_fp = fopen(infile, "r");
	if(!in_fp) {
		printf("open %s fail\n", infile);
		close(fdwr);
		return -1;
	}

	ret_code = ioctl(fdwr, VIDIOC_QUERYCAP, &vid_caps);
	assert(ret_code != -1);

	memset(&vid_format, 0, sizeof(vid_format));

	ret_code = ioctl(fdwr, VIDIOC_G_FMT, &vid_format);

	vid_format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
	vid_format.fmt.pix.width = FRAME_WIDTH;
	vid_format.fmt.pix.height = FRAME_HEIGHT;
	vid_format.fmt.pix.pixelformat = FRAME_FORMAT;
	vid_format.fmt.pix.sizeimage = framesize;
	vid_format.fmt.pix.field = V4L2_FIELD_NONE;
	vid_format.fmt.pix.bytesperline = FRAME_WIDTH * 15 / 10 / 8;
	vid_format.fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;

	ret_code = ioctl(fdwr, VIDIOC_S_FMT, &vid_format);
	assert(ret_code != -1);

	buffer=(__u8*)malloc(sizeof(__u8)*framesize);

	printf("sleep 3\n");
	//wait for consumer	
	sleep(4);
	printf("go .....\n");

	int frame_cnt = 0;
	while(fread(buffer, 1, framesize, in_fp) == framesize) {
		write(fdwr, buffer, framesize);
		//delay 30ms -> 30fps
		usleep(FPS*1000);
		frame_cnt ++; 
	}

	printf("frame_cnt = %d\n", frame_cnt);
	sleep(3);

	fclose(in_fp);
	close(fdwr);
	free(buffer);

	return 0;
}
